/*
 
 */
package com.jme3.gde.gui.extra.xam.model.spi;

import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import com.jme3.gde.gui.extra.xam.model.NiftyComponent;
import com.jme3.gde.gui.extra.xam.model.NiftyComponentFactory;
import com.jme3.gde.gui.extra.xam.model.NiftyModel;
import com.jme3.gde.gui.extra.xam.model.NiftyQName;
import com.jme3.gde.gui.extra.xam.model.NiftyExtensibilityElement;
import com.jme3.gde.gui.extra.xam.model.ReferenceableNiftyComponent; 
import com.jme3.gde.gui.extra.xam.model.impl.GlobalReferenceImpl;
import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
import org.netbeans.modules.xml.xam.dom.Attribute;
import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Abstract implementation of the base component in the Nifty domain.
 *
 * @author cuongnguyen
 */
// Generated by XAM AutoGen Tool v0.2
public abstract class NiftyComponentBase extends AbstractDocumentComponent<NiftyComponent>
        implements NiftyComponent {

   public NiftyComponentBase(NiftyModel model, Element e) {
        super(model, e);
    }
    
    @Override
    protected String getNamespaceURI() {
        return NiftyQName.NS_URI;
    }
        
    @Override
    public NiftyModel getModel() {
        return (NiftyModel) super.getModel();
    }
    
    protected void populateChildren(List<NiftyComponent> children) {
        //System.out.println("populateChildren: " + getPeer().getNodeName());
        NodeList nl = getPeer().getChildNodes();
        if (nl != null){
            NiftyModel model = getModel();
            NiftyComponentFactory componentFactory = model.getFactory();
            for (int i = 0; i < nl.getLength(); i++) {
                Node n = nl.item(i);
                if (n instanceof Element) {
                    NiftyComponent comp = componentFactory.create((Element)n, this);
                    if (comp != null) {
                        children.add(comp);
                    }
                }
            }
        }
    }

    protected Object getAttributeValueOf(Attribute attribute, String stringValue) {
        return stringValue;
    }  
    
    public static Element createElementNS(NiftyModel model, NiftyQName rq) {
        return model.getDocument().createElementNS(
                rq.getQName().getNamespaceURI(), rq.getQualifiedName());
    }
        
    protected <T extends ReferenceableNiftyComponent> NamedComponentReference<T> 
            resolveGlobalReference(Class<T> c, Attribute attrName) {        
        String v = getAttribute(attrName);
        return v == null ? null : new GlobalReferenceImpl<T>(c, this, v);
    }
    
    public <T extends ReferenceableNiftyComponent> NamedComponentReference<T> 
            createReferenceTo(T target, Class<T> type) {        
        return new GlobalReferenceImpl<T>(target, type, this);
    }

    public void removeExtensibilityElement(NiftyExtensibilityElement ee) {
        removeChild(EXTENSIBILITY_ELEMENT_PROPERTY, ee);
    }
    
    public void addExtensibilityElement(NiftyExtensibilityElement ee) {
        appendChild(EXTENSIBILITY_ELEMENT_PROPERTY, ee);
    }
    
    public List<NiftyExtensibilityElement> getExtensibilityElements() {
        return getChildren(NiftyExtensibilityElement.class);
    }
    
    public <T extends NiftyExtensibilityElement> List<T> getExtensibilityElements(Class<T> type) {
        return getChildren(type);
    }

    protected static Element createPrefixedElement(QName qName, NiftyModel model){
        String qualified = qName.getPrefix() == null ? qName.getLocalPart() : 
            qName.getPrefix() + ":" + qName.getLocalPart(); // NOI18N
        return model.getDocument().createElementNS(qName.getNamespaceURI(), qualified);
    }

    // This is to get around an issue in AbstractDocumentComponent where
    // prefixed name doesn't get generated properly when the QName has a 
    // default namespace.
    @Override
    protected String getPrefixedName(QName qname, boolean declarePrefix) {
        if (XMLConstants.DEFAULT_NS_PREFIX.equals(qname.getPrefix())) {
            return getPrefixedName(qname.getNamespaceURI(), 
                    qname.getLocalPart(), null, declarePrefix);
        } else {
            return super.getPrefixedName(qname, declarePrefix);
        }
    }

    /**
     * Utility method to get the QName of a QName-type attribute value.
     * @param qNameTypeAttributeValue
     * @return
     */
    protected QName getQName(String qNameTypeAttributeValue) {
        QName ret = null;
        if (qNameTypeAttributeValue != null) {
            int colonIndex = qNameTypeAttributeValue.indexOf(":");  // NOI18N
            if (colonIndex != -1) {
                String prefix = qNameTypeAttributeValue.substring(0, colonIndex);
                String localPart = qNameTypeAttributeValue.substring(colonIndex + 1);
                String namespaceURI = lookupNamespaceURI(prefix);
                ret = new QName(namespaceURI, localPart, prefix);
            } else {
                String localPart = qNameTypeAttributeValue;
                String namespaceURI = lookupNamespaceURI(null);
                ret = new QName(namespaceURI, localPart);
            }
        }
        return ret;
    }   
    
}

